package com.hcc.gateway.app.filter;

import com.hcc.gateway.app.constant.HccGatewayAppConstant;
import com.hcc.gateway.domain.enums.ApiStatusEnum;
import com.hcc.gateway.domain.po.ApiConfigPo;
import com.hcc.gateway.netty.context.GatewayExchange;
import com.hcc.gateway.netty.context.ReqContext;
import com.hcc.gateway.netty.context.RespContext;
import com.hcc.gateway.netty.filter.AbstractMatchRouteFilter;
import com.hcc.gateway.netty.route.GatewayRoute;
import com.hcc.gateway.service.ApiConfigService;
import io.netty.handler.codec.http.HttpResponseStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.URI;

/**
 * DefaultMatchRouteFilter
 *
 * @author shengjun.hu
 * @date 2021/12/29
 */
@Slf4j
@Component
public class MatchRouteFilter extends AbstractMatchRouteFilter {

    @Autowired
    private ApiConfigService apiConfigService;

    @Override
    public int getOrder() {
        return 150;
    }

    @Override
    public GatewayRoute matchRoute(GatewayExchange exchange) {
        log.info("进入MatchRouteFilter !");
        ReqContext reqContext = exchange.getReqContext();
        ApiConfigPo apiConfig = this.getApiConfig(reqContext.getUri());
        if (apiConfig == null) {
            return null;
        }

        GatewayRoute route = new GatewayRoute();
        route.setOrder(apiConfig.getId().intValue());
        route.setUri(URI.create(apiConfig.getTargetUrl()));
        exchange.addAttribute(HccGatewayAppConstant.HCC_API_CONFIG, apiConfig);

        return route;
    }

    private ApiConfigPo getApiConfig(String path) {
        return apiConfigService.lambdaQuery()
                .eq(ApiConfigPo::getPath, path)
                .eq(ApiConfigPo::getStatus, ApiStatusEnum.ONLINE.name())
                .one();
    }

    @Override
    public void matchRouteFiled(GatewayExchange exchange) {
        RespContext respContext = exchange.getRespContext();
        respContext.setHttpStatus(HttpResponseStatus.NOT_FOUND);
        throw new RuntimeException("未匹配到路由！");
    }

}
